package de.lighti.starcraft.model;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;

public class StarcraftMap implements Serializable, Cloneable {

    /**
     * 
     */
    private static final long serialVersionUID = -4209225643430248698L;
    /** This maps name */
    private final String mapName;
    /** This maps file location relative to the starcraft directory */
    private final String mapLocation;

    private final String bwtaHash;

    private transient ByteBuffer[] binaryContent;

    private StarcraftMap( StarcraftMap other ) {
        this( other.mapName, other.mapLocation, other.bwtaHash );
    }

    /**
     * The constructor for the map class. Sets the map's name and relative
     * location to the starcraft directory.
     * 
     * @param mapName
     *            the maps name
     * @param mapLocation
     *            the maps location relative to the starcraft directory
     */
    public StarcraftMap( String mapName, String mapLocation ) {
        this.mapName = mapName;
        this.mapLocation = mapLocation;
        bwtaHash = null;
    }

    public StarcraftMap( String mapName, String mapLocation, String bwtaHash ) {
        this.mapName = mapName;
        this.mapLocation = mapLocation;
        this.bwtaHash = bwtaHash;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return new StarcraftMap( this );
    }

    public ByteBuffer[] getBinaryContent() {
        return binaryContent;
    }

    public String getBWTAHash() {
        return bwtaHash;
    }

    /**
     * Returns the map's file location relative to the starcraft directory.
     * 
     * @return the mapLocation
     */
    public String getMapLocation() {
        return mapLocation;
    }

    public String getName() {
        return mapName;
    }

    private void readObject( ObjectInputStream ois ) throws ClassNotFoundException, IOException {
        // default deserialization
        ois.defaultReadObject();

        //Transient field
        final boolean hasbinary = ois.readBoolean();

        if (hasbinary) {
            final byte[] bytes = (byte[]) ois.readObject();
            if (bwtaHash != null) {
                binaryContent = new ByteBuffer[2];
            }
            else {
                binaryContent = new ByteBuffer[1];
            }
            binaryContent[0] = ByteBuffer.wrap( bytes );

            if (bwtaHash != null) {
                final byte[] bwtabytes = (byte[]) ois.readObject();
                binaryContent[1] = ByteBuffer.wrap( bwtabytes );
            }
        }

    }

    public void setBinaryContent( ByteBuffer[] binaryContent ) {
        this.binaryContent = binaryContent;
    }

    @Override
    public String toString() {
        return "StarcraftMap [mapName=" + mapName + ", mapLocation=" + mapLocation + ", bwtaHash=" + bwtaHash + "]";
    }

    private void writeObject( ObjectOutputStream oos ) throws IOException {
        // default serialization 
        oos.defaultWriteObject();

        //Transient field

        if (binaryContent != null) {
            oos.writeBoolean( true );
            binaryContent[0].rewind();
            oos.writeObject( binaryContent[0].array() );
            if (bwtaHash != null) {
                binaryContent[1].rewind();
                oos.writeObject( binaryContent[1].array() );
            }

        }
        else {
            oos.writeBoolean( false );
        }
    }
}
